<?xml version="1.0"?>
<rss version="2.0">
  <channel><title>Java Bridge</title><link>http://bill.welliver.org//space/pike/Java Bridge</link><description>This is a very slightly prettied up version of the presentation I gave at the 2003 Pike Conference in Paderborn. It's basically an overview of what's going on in the Java module. Contact me if you're interested in having a copy of the original text document (it might be easier to read in certain situations).&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;JNI Specification&lt;/b&gt;&lt;p class="paragraph"/&gt;
Defines methods for embedding a Java VM within an application.&#xD;
Access to Java objects from the application embedding the Java VM.&#xD;
Provides access to functions within the application to the embedded Java VM (native methods)&lt;p class="paragraph"/&gt;
&lt;span class="nobr"&gt;&lt;img height="9" width="8" src="/static/images/Icon-Extlink.png" alt="&amp;#91;external]"/&gt;&lt;a href="http://java.sun.com/products/jdk/1.2/docs/guide/jni/"&gt;http://java.sun.com/products/jdk/1.2/docs/guide/jni/&lt;/a&gt;&lt;/span&gt;&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;The Pike Implementation&lt;/b&gt;&lt;p class="paragraph"/&gt;
Located in the Java module.&#xD;
Supported on systems containing a Java v1.2+ installation.&#xD;
Known to work with both the Sun JDK and IBM JDK&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Using the Java bridge.&lt;/b&gt;&#xD;
&lt;ul class="minus"&gt;
&lt;li&gt;The Hard Way&lt;/li&gt;
&lt;/ul&gt;  Java.machine&#xD;
     starts up a Java VM and leaves the rest to you&lt;p class="paragraph"/&gt;
     Pros: Less overhead (speed and memory-wise), more direct control of your &#xD;
       interaction with the Java VM&#xD;
     Cons: Tedious, time-consuming to set up, not very Pikeish&#xD;
&lt;ul class="minus"&gt;
&lt;li&gt;The Easy Way&lt;/li&gt;
&lt;/ul&gt;  Java.pkg&#xD;
     will load a java package and connect all of the functions and fields so &#xD;
     that they (nominally) act like other pike objects.&lt;p class="paragraph"/&gt;
     Pros: much easier to access Java functionality&#xD;
     Cons: slower, due to object setup and wrappings, less control over how &#xD;
       things are set up and connected, doesn't completely hide you from &#xD;
       Javaness&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java VM&lt;/b&gt;&lt;p class="paragraph"/&gt;
create(string|void arg)&#xD;
  In theory, you should be able to start a vm with arg as the classpath. &#xD;
  In reality, this doesn't work so well.&lt;p class="paragraph"/&gt;
int get_version()&#xD;
  Returns the version code of the JVM running.&lt;p class="paragraph"/&gt;
object find_class(string c)&#xD;
  Finds the class c, using "/" instead of "." as the class separator.&#xD;
  Returns the class or zero if the class was not found, in addition to &#xD;
  throwing an exception.&lt;p class="paragraph"/&gt;
object define_class(object cl, string bc)&#xD;
  prepare a java class object from a string of java bytecode&#xD;
  cl is a class loader object&#xD;
  Note: doesn't seem to work properly.&lt;p class="paragraph"/&gt;
int exception_check()&#xD;
  checks to see if an exception is being thrown.&lt;p class="paragraph"/&gt;
object exception_occurred()&#xD;
  returns the exception object, if one has been thrown.&lt;p class="paragraph"/&gt;
void exception_describe()&#xD;
  prints an exception description and backtrace to stderr&lt;p class="paragraph"/&gt;
void exception_clear()&#xD;
  clears any exceptions&lt;p class="paragraph"/&gt;
void  fatal(string arg)&#xD;
  Raises a fatal error; the VM quits, taking Pike with it.&lt;p class="paragraph"/&gt;
object new_boolean_array(int)&lt;p class="paragraph"/&gt;
object new_byte_array(int)&#xD;
object new_char_array(int)&#xD;
object new_short_array(int)&#xD;
object new_int_array(int)&#xD;
object new_long_array(int)&#xD;
object new_float_array(int)&#xD;
object new_double_array(int)&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java Object:&lt;/b&gt;&lt;p class="paragraph"/&gt;
mixed cast(string)&#xD;
  casts the object to another datatype. Currently, only casting to string is &#xD;
  supported.&lt;p class="paragraph"/&gt;
int `==(mixed)&#xD;
  are two objects the same?&lt;p class="paragraph"/&gt;
int _ _hash()&#xD;
  calls the hashCode method of the object&lt;p class="paragraph"/&gt;
int is_instance_of(object arg)&#xD;
  determines whether the object is an instance of arg&lt;p class="paragraph"/&gt;
object monitor_enter()&#xD;
  returns a Java.monitor object&lt;p class="paragraph"/&gt;
object get_object_class()&#xD;
  returns the class of an object&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java Class:&lt;/b&gt;&#xD;
inherits Java Object&lt;p class="paragraph"/&gt;
object register_natives(array(array(string|function)) arg)&#xD;
  registers one or more native methods for a class. the class must have the &#xD;
  functions defined as "native"&lt;p class="paragraph"/&gt;
  arg&amp;#91;n]&amp;#91;0] is a string containing the method name to define&#xD;
  arg&amp;#91;n]&amp;#91;1] is a string describing the method signature to define for the given &#xD;
  method&#xD;
  arg&amp;#91;n]&amp;#91;2] is a function to be called when the method is called from Java&lt;p class="paragraph"/&gt;
object|0 super_class()&#xD;
  Returns the superclass of the object, zero if the object is a &#xD;
  java.lang.Object.&lt;p class="paragraph"/&gt;
int is_assignable_from(object c)&#xD;
 Returns TRUE if:&#xD;
  The argument refers to the same Java class as the object itself.&#xD;
  The argument class is a subclass of the object.&#xD;
  The argument has the object as one of its interfaces.&lt;p class="paragraph"/&gt;
void throw_new(string arg)&#xD;
 Throws an exception or error (if the object is a child one of these classes), &#xD;
 with the optional description of arg&#xD;
 Produces an exception that may be caught or checked using one of the exception &#xD;
 checks.&lt;p class="paragraph"/&gt;
object alloc()&#xD;
  allocates a new Java object without invoking its constructors. returns the &#xD;
  new object.&lt;p class="paragraph"/&gt;
object new_array(int, object|void)&lt;p class="paragraph"/&gt;
&#xD;
object get_method(string name, string sig)&#xD;
  gets method name with signature sig from the class. returns the method or &#xD;
  zero if the name and signature do not match any in the class.&lt;p class="paragraph"/&gt;
object get_static_method(string, string)&#xD;
  gets a static method name with signature sig from the class. returns the &#xD;
  method or zero if the name and signature do not match any in the class.&lt;p class="paragraph"/&gt;
object get_field(string name, string sig)&#xD;
  gets a field name with a type of sig from the class. returns the&#xD;
  field object or zero if the name and signature do not match any in the class.&lt;p class="paragraph"/&gt;
object get_static_field(string, string)&#xD;
  gets a static field name with a type of sig from the class. returns the&#xD;
  field object or zero if the name and signature do not match any in the class.&lt;p class="paragraph"/&gt;
&#xD;
&lt;b class="bold"&gt;Java Throwable&lt;/b&gt;&#xD;
inherits Java Object&lt;p class="paragraph"/&gt;
void throw()&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java Array&lt;/b&gt;&#xD;
inherits Java Object&#xD;
_sizeof()&#xD;
`&amp;#91;]&#xD;
`&amp;#91;]=&#xD;
_indices&#xD;
_values&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java Static Method&lt;/b&gt;&lt;p class="paragraph"/&gt;
mixed `(mixed&amp;#8230; args)&#xD;
  calls the method with arguments args.&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java Method&lt;/b&gt;&lt;p class="paragraph"/&gt;
mixed `(object obj, mixed&amp;#8230; args)&#xD;
  calls the method as defined in object obj, with arguments args.&lt;p class="paragraph"/&gt;
mixed call_nonvirtual(object obj, mixed &amp;#8230; args)&#xD;
  calls the method as defined in the class the method is derived from, with &#xD;
  arguments args.&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java Field &amp; Static Fields&lt;/b&gt;&lt;p class="paragraph"/&gt;
mixed set(mixed val)&#xD;
  sets the value of a field to val.&lt;p class="paragraph"/&gt;
mixed get()&#xD;
  returns the value of a field&lt;p class="paragraph"/&gt;
Objects used internally by the module:&lt;p class="paragraph"/&gt;
  Java Monitor&#xD;
  Java Natives&#xD;
  Java Attachment&lt;p class="paragraph"/&gt;
  &#xD;
&lt;b class="bold"&gt;The Java Package interface&lt;/b&gt;&lt;p class="paragraph"/&gt;
The Java.package module provides convenient access to an entire Java Class &#xD;
package, performing a number of useful tricks along the way.&lt;p class="paragraph"/&gt;
The module will look for a package, load the class, set up access to all of &#xD;
its fields and methods, making it look very much like a Pike object.&lt;p class="paragraph"/&gt;
Usage: &#xD;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
        &amp;gt; &lt;b&gt;&lt;font color=darkgreen&gt;object &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;i=Java.pkg&amp;amp;#91&lt;/font&gt;&lt;/b&gt;;&lt;i&gt;&lt;font color=darkred&gt;"java/lang/Integer"&lt;/font&gt;&lt;/i&gt;];&#xD;
        &amp;gt; i(52);&#xD;
        &amp;gt; indices(i);&#xD;
        Result: ({ &lt;font color=red&gt;/* 14 elements */&lt;/font&gt;&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"wait"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"getClass"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"doubleValue"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"longValue"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"toString"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"equals"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"compareTo"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"hashCode"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"floatValue"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"shortValue"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"notifyAll"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"notify"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"intValue"&lt;/font&gt;&lt;/i&gt;,&#xD;
                &lt;i&gt;&lt;font color=darkred&gt;"byteValue"&lt;/font&gt;&lt;/i&gt;&#xD;
            })&#xD;
          &amp;gt; (&lt;b&gt;&lt;font color=darkgreen&gt;string&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;&lt;/font&gt;&lt;/b&gt;)i-&amp;gt;toString();&#xD;
          Result: &lt;i&gt;&lt;font color=darkred&gt;"52"&lt;/font&gt;&lt;/i&gt;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
          &#xD;
What the Java.package module does not do:&#xD;
&lt;ul class="minus"&gt;
&lt;li&gt;convert Pike datatypes into Java datatype objects&lt;/li&gt;
&lt;li&gt;convert Java datatype objects into Pike datatypes&lt;/li&gt;
&lt;li&gt;attempt to guess what function signature you wish to use if it's at all ambiguous.&lt;/li&gt;
&lt;li&gt;completely mask the Java bridge and its Javaness from the Pike user, though it comes quite a bit of the way.&lt;/li&gt;
&lt;/ul&gt;&lt;b class="bold"&gt;Using Java.package&lt;/b&gt;&#xD;
  The package interface to Java is straightforward in use. The Java module&#xD;
  creates an instance of the package interface called "pkg" on startup.&lt;p class="paragraph"/&gt;
  The package interface exposes its functionality by overloading the indexing &#xD;
  operator.&lt;p class="paragraph"/&gt;
  To access a java class, simply ask Java.pkg for it:&lt;p class="paragraph"/&gt;
  &gt; object myclass = Java.pkg&amp;#91;"org/welliver/conference/myclass"];&#xD;
  Result: Java.jclass()&lt;p class="paragraph"/&gt;
  An error will be thrown if the requested class cannot be found.&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java.jclass&lt;/b&gt;&#xD;
  represents a Java Class in Pike.&lt;p class="paragraph"/&gt;
  `(mixed &amp;#8230; args) calls the constructor that most closely matches args. will&#xD;
     not attempt to choose if more than one method signature matches.&#xD;
  `&amp;#91;n] returns the value of a static field n or a static method object n&#xD;
  `-&gt;n returns the value if `&amp;#91;n] unless n&amp;#91;0..0]=="_", in which case it returns:&lt;p class="paragraph"/&gt;
    _fields:  returns a mapping of the field objects in the class&#xD;
    _static_fields: returns a mapping of the static field objects in the class&#xD;
    _methods: returns a mapping of the method objects in the class&#xD;
    _static_methods: returns a mapping of the method objects in the class&#xD;
    _wrap_result: returns the wrap result function, used to turn a Java.object &#xD;
      into a Java.jobject&#xD;
    _method: returns the method selector function&#xD;
    _constructor: returns the constructor selector function&#xD;
    _alloc: returns the alloc function of the base Java.object&#xD;
    _register_natives: returns the register_natives function of the base &#xD;
      Java.object&lt;p class="paragraph"/&gt;
    Java.jmethod _method(string n, string sig) &#xD;
      returns the java method that matches name n and type signature sig.&#xD;
    Java.jconstructor _constructor(string sig)&#xD;
       returns the java constructor for this class that matches type signature &#xD;
       sig.&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java.jconstructor&lt;/b&gt;&#xD;
  represents a Java constructor in Pike.&lt;p class="paragraph"/&gt;
  Java.jobject `(mixed &amp;#8230; args)&#xD;
    calls the constructor of the class with arguments args.&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java.jmethod&lt;/b&gt;&#xD;
  represents a Java method in Pike.&lt;p class="paragraph"/&gt;
  Java.jobject `(mixed &amp;#8230; args)&#xD;
    calls the function with arguments args.&lt;p class="paragraph"/&gt;
  Java.method for_protos(string sig)&#xD;
     returns the Java method matching the type signature sig. Used internally.&lt;p class="paragraph"/&gt;
  Java.jmethod for_object(object obj)&#xD;
      returns a jmethod object for the object obj. Used internally.&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java.jobject&lt;/b&gt;&#xD;
  represents a Java object in Pike.&lt;p class="paragraph"/&gt;
  cast(mixed type)&#xD;
     calls the cast function for the underlying Java object. Note that this&#xD;
     only works with the argument of "string".&lt;p class="paragraph"/&gt;
&#xD;
  `&amp;#91;n]&#xD;
    returns the field or method n from the class.&#xD;
  `-&gt;n&#xD;
    returns the value of `&amp;#91;n] unless n&amp;#91;0..0]=="_", in which case it returns:&lt;p class="paragraph"/&gt;
    _method: returns the method selector function.&#xD;
    _obj: returns the low level Java.object object.&#xD;
    _monitor_enter: returns the Java.monitor object associated with this class.&lt;p class="paragraph"/&gt;
  _values()&#xD;
    returns the values of the object, matching its indices.&#xD;
  _indices()&#xD;
    returns the indices of the object, ie field and method names.&lt;p class="paragraph"/&gt;
  Java.jmethod _method(string n, string sig) &#xD;
    returns the java method that matches name n and type signature sig.&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java.jarray&lt;/b&gt;&#xD;
   represents a Java array in Pike.&lt;p class="paragraph"/&gt;
   cast(mixed &amp;#8230; arg)&lt;p class="paragraph"/&gt;
   `&amp;#91;n] &#xD;
     returns the nth element of the array:&lt;p class="paragraph"/&gt;
     length: returns the number of elements in the array&#xD;
     _monitor_enter: returns the monitor object associated with this instance&#xD;
     _obj: returns the low level object for this array&lt;p class="paragraph"/&gt;
   `&amp;#91;n]=x&#xD;
     attempts to set the value of the nth element to x.&lt;p class="paragraph"/&gt;
   `-&gt;n&#xD;
     returns the following:&lt;p class="paragraph"/&gt;
     length: returns the number of elements in the array&#xD;
     _monitor_enter: returns the monitor object associated with this instance&#xD;
     _obj: returns the low level object for this array&lt;p class="paragraph"/&gt;
   _sizeof()&#xD;
   _indices()&#xD;
   _values()&lt;p class="paragraph"/&gt;
     overloads to make an array object seem more Pikeish.&lt;p class="paragraph"/&gt;
&lt;b class="bold"&gt;Java Convenience Functions&lt;/b&gt;&lt;p class="paragraph"/&gt;
The following functions will convert a Pike datatype to a relatively common &#xD;
Java equivalent. Their behavior is general, and any value may be provided to &#xD;
them, as long as they are the specified type. Any exceptions are noted below.&lt;p class="paragraph"/&gt;
Java.JInteger(int i)&#xD;
Java.JString(string s)&#xD;
Java.JFloat(float f)&#xD;
Java.JBoolean(int b)&#xD;
  any value other than 0 is true, 0 is false.&#xD;
Java.JArray(array(mixed) a)&#xD;
  can encode an array of any type, however all of the elements must be the &#xD;
  same type. that is, you may not mix strings and floats as values in the array&#xD;
Java.JHashMap(mapping m)&#xD;
Java.JVector(multiset x)&#xD;
</description><generator>Fins 0.9.7</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs></channel>
</rss>
